from odoo import api, models, fields, _
from odoo.exceptions import ValidationError


class DelinkApply(models.Model):
    _name = 'delink.apply'
    _inherit = ['portal.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']

    def _default_name(self):
        return self.env['ir.sequence'].next_by_code('delink.apply')

    name = fields.Char(string='Ref', default=_default_name)
    sb_workflow_template_id = fields.Many2one('sb.workflow.template', string="Approval Workflow Template",
                                              domain="[('sb_workflow_template_item_ids', '!=', False),"
                                                     "('workflow_type', '=', 'delink_apply')]")

    sb_workflow_id = fields.Many2one('sb.workflow', string="Current Approval Workflow", copy=False)
    sb_workflow_state = fields.Selection(related="sb_workflow_id.state", readonly=True, string="Approval Status",
                                         store=True)
    sb_workflow_item_ids = fields.One2many(related="sb_workflow_id.sb_workflow_item_ids", string="Approval Items")
    sb_workflow_attachments_ids = fields.One2many(related="sb_workflow_id.sb_workflow_attachments_ids",
                                                  string="Approval Attachments")
    sb_workflow_ids = fields.One2many('sb.workflow', 'delink_apply_id', string="Approval Workflows")
    sb_workflow_ids_sum = fields.Integer(compute="_compute_sb_workflow_ids_sum", store=True)
    note = fields.Text(string='Note')
    delink_mo = fields.Boolean(default=False, string='Delink Mrp')
    link_mo = fields.Boolean(default=False, string='Link Mrp')
    sale_order_id = fields.Many2one('sale.order', string='Sale Order')
    partner_id = fields.Many2one('res.partner', string='Customer', related='sale_order_id.partner_id')
    product_tmpl_id = fields.Many2one('product.template', related='sale_order_id.product_tmpl_id')
    link_or_delink = fields.Selection(related='sale_order_id.link_or_delink')
    line_ids = fields.One2many('delink.apply.line', 'delink_apply_id', string='Order Lines')
    link_mo_ids = fields.One2many('sb.sale.link.mo', 'delink_apply_id')

    @api.onchange('link_mo')
    def onchange_delink_mo(self):
        if self.link_mo:
            self.delink_mo = False
        else:
            self.delink_mo = True

    @api.onchange('delink_mo')
    def onchange_link_mo(self):
        if self.delink_mo:
            self.link_mo = False
        else:
            self.link_mo = True

    @api.depends('sb_workflow_ids')
    def _compute_sb_workflow_ids_sum(self):
        for item in self:
            if item.sb_workflow_ids:
                item.sb_workflow_ids_sum = len(item.sb_workflow_ids)
            else:
                item.sb_workflow_ids_sum = 0

    def create_workflow(self):
        if self.sb_workflow_template_id:
            if len(self.sb_workflow_ids) > 0:
                workflow_sum = len(self.sb_workflow_ids) + 1
            else:
                workflow_sum = 1
            # 创建审批流
            new_wf_id = self.env['sb.workflow'].sudo().create({
                'name': self.name + '- Approval Flow' + '-' + str(workflow_sum),
                'approval_time': fields.Datetime.now(),
                'workflow_type': 'delink_apply',
                'delink_apply_id': self.id,
            })
            self.sb_workflow_id = new_wf_id.id
            # 根据模板生成审批项
            item_audit_levels = []
            for item in self.sb_workflow_template_id.sb_workflow_template_item_ids:
                new_item = self.env['sb.workflow.item'].sudo().create({
                    'name': item.name,
                    'user_group_ids': item.user_group_ids.ids,
                    'audit_level': item.audit_level,
                    'sb_workflow_id': new_wf_id.id,
                    'state': 'wait_forward'
                })
                # 收集生成的审核项的所有层级
                item_audit_levels.append(new_item.audit_level)
            # 去重排序
            item_audit_levels = list(set(item_audit_levels))
            item_audit_levels.sort()
            # 开放最低层级的神匹配
            for n_item in new_wf_id.sb_workflow_item_ids:
                if n_item.audit_level == item_audit_levels[0]:
                    n_item.state = 'approval'
        else:
            raise ValidationError(_('Please select an approval template.'))

    def search_action(self):
        if not self.sale_order_id:
            raise ValidationError('请先选择销售订单！')
        context = dict(self._context)
        line_vals = []
        if self.delink_mo:
            # 断开工单, 获取已经和so连接的MO
            for line in self.sale_order_id.order_line:
                if line.product_id.detailed_type == 'product':
                    for mrp in line.s_mrp_production_ids:
                        line_vals.append((0, 0, {'mrp_production_id': mrp.id, 'sale_order_line_id': line.id}))
        else:
            # 连接工单,查找 没有和so连接的mo
            product_ids = []
            for line in self.sale_order_id.order_line:
                if line.product_id.detailed_type == 'product':
                    product_ids.append(line.product_id.id)
            mrp_production_ids = self.sudo().env['mrp.production'].search(
                [('customer', '=', self.partner_id.id),
                 ('product_id', 'in', product_ids),
                 ('state', 'not in', ['to_close', 'cancel', 'done'])])
            if not mrp_production_ids:
                pass
            else:
                select = """SELECT m.id as mid, sol.id as solid 
                            FROM mrp_production as m, sale_order_line as sol"""
                where = """ WHERE m.product_id = sol.product_id
                            AND sol.order_id = {}
                            AND m.id not in (SELECT mrp_production_id FROM mrp_production_sale_order_line_rel)""".format(self.sale_order_id.id)
                if len(mrp_production_ids) > 1:
                    where += """ AND m.id in {}""".format(tuple(mrp_production_ids.ids))
                else:
                    where += """ AND m.id = {}""".format(mrp_production_ids.ids[0])
                if len(product_ids) > 1:
                    where += """ AND sol.product_id in {}""".format(tuple(product_ids))
                else:
                    where += """ AND sol.product_id = {}""".format(product_ids[0])

                sql = select + where
                self.env.cr.execute(sql)
                s_mrp_production_ids = self.env.cr.dictfetchall()
                self.env.cr.commit()
                line_vals = [(0, 0, {'mrp_production_id': mrp['mid'], 'sale_order_line_id': mrp['solid']}) for mrp in
                             s_mrp_production_ids]
        context['default_line_ids'] = line_vals
        context['default_delink_mo'] = self.delink_mo
        context['default_link_mo'] = self.link_mo
        context['default_delink_apply_id'] = self.id
        return {
            'name': _('Delink Apply Wizard'),
            'type': 'ir.actions.act_window',
            'res_model': 'delink.apply.wizard',
            'view_mode': 'form',
            'target': 'new',
            'context': context
        }


class DelinkApplyLine(models.Model):
    _name = 'delink.apply.line'

    delink_apply_id = fields.Many2one('delink.apply')
    mrp_production_id = fields.Many2one('mrp.production', string='Mrp')
    state = fields.Selection(related='mrp_production_id.state', string='Mrp Statu')
    date_start = fields.Datetime(related='mrp_production_id.date_start')
    date_finished = fields.Datetime(related='mrp_production_id.date_finished')
    product_qty = fields.Float(related='mrp_production_id.product_qty', string='Mrp Qty')
    sale_order_line_id = fields.Many2one('sale.order.line', string='Order Line')
